import 'dart:async';
// import 'package:flutter_downloader/flutter_downloader.dart';
import 'package:open_file/open_file.dart';
import 'package:path_provider/path_provider.dart';
import 'package:permission_handler/permission_handler.dart';
import 'package:dio/dio.dart';
import 'package:archive/archive.dart';
import 'dart:io';

enum DownloadStatus { notStarted, downloading, completed, failed }

@pragma('vm:entry-point') // 关键注解：声明为VM入口点
class DownloadService {
  static final StreamController<double> _progressController =
  StreamController<double>.broadcast();
  static final StreamController<DownloadStatus> _statusController =
  StreamController<DownloadStatus>.broadcast();

  static Stream<double> get progressStream => _progressController.stream;
  static Stream<DownloadStatus> get statusStream => _statusController.stream;

  static String? _taskId;
  static String? _downloadedFilePath;
  static CancelToken? _cancelToken;

  static Future<void> init() async {
    // await FlutterDownloader.initialize(debug: true);
    // FlutterDownloader.registerCallback(downloadCallback);
  }

  @pragma('vm:entry-point')
  static void downloadCallback(String id, int status, int progress) {
    if (_taskId == id) {
      _progressController.add(progress / 100.0);

      if (status == 2) {
        _statusController.add(DownloadStatus.completed);
      } else if (status == 3) {
        _statusController.add(DownloadStatus.failed);
      }
    }
  }

  static Future<void> downloadApk({
    required String url,
    required String fileName,
  }) async {
    // 请求存储权限
    final status = await Permission.storage.request();
    if (!status.isGranted) {
      //openAppSettings();
      // throw Exception('存储权限被拒绝');
    }

    // 获取下载目录
    final directory = await getExternalStorageDirectory();
    if (directory == null) {
      throw Exception('无法访问存储目录');
    }

    final savePath = '${directory.path}/$fileName';
    final compressedPath = '${directory.path}/$fileName.zip';

    // // 启动下载
    // _taskId = await FlutterDownloader.enqueue(
    //   url: url,
    //   savedDir: directory.path,
    //   fileName: fileName,
    //   showNotification: true,
    //   openFileFromNotification: false,
    // );
    //
    // if (_taskId == null) {
    //   throw Exception('下载任务启动失败');
    // }
    _statusController.add(DownloadStatus.downloading);
    _downloadedFilePath = savePath;
// 下载APK
    Dio dio = Dio();

    try {
      await dio.download(
        url,
        compressedPath,
        cancelToken: _cancelToken,
        onReceiveProgress: (received, total) {
          double progress = received / total;
          _progressController.add(progress);
          // print('下载进度: ${(progress * 100).toStringAsFixed(1)}%');
        },
      );
      await _extractApk(compressedPath, savePath);
      _statusController.add(DownloadStatus.completed);

    } on DioException catch (e) {
      if (CancelToken.isCancel(e)) {
        print('下载已取消');
      } else {
        _statusController.add(DownloadStatus.failed);
      }
    } finally {

    }

  }
  static Future<String> _extractApk(String compressedPath, String apkPath) async {
    final bytes = File(compressedPath).readAsBytesSync();
    final archive = ZipDecoder().decodeBytes(bytes);

    // final dir = await getTemporaryDirectory();
    // final apkPath = '${dir.path}/app.apk';
    print('_extractApk $compressedPath , apkPath=$apkPath');
    for (final file in archive) {
      if (file.name.endsWith('.apk')) {
        final data = file.content as List<int>;
        File(apkPath)
          ..createSync(recursive: true)
          ..writeAsBytesSync(data);
        break;
      }
    }

    // 删除压缩包
    File(compressedPath).deleteSync();

    return apkPath;
  }
  static void cancelDownload() async {
    if (_taskId != null) {
      // await FlutterDownloader.cancel(taskId: _taskId!);
      _taskId = null;
      _cancelToken?.cancel('用户取消');
    }
  }

  static Future<void> installApk() async {
    if (_downloadedFilePath == null) {
      throw Exception('没有可安装的APK文件');
    }

    // 请求安装未知来源应用的权限
    final status = await Permission.requestInstallPackages.request();
    if (!status.isGranted) {
      throw Exception('安装权限被拒绝');
    }

    final result = await OpenFile.open(_downloadedFilePath);

    if (result.type != ResultType.done) {
      throw Exception('安装失败: ${result.message}');
    }
  }
}